﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace NetWork
{
    /// <summary>
    /// 一个简单的不持久化的序号自增类，采用线程安全实现，并允许指定最大数字，到达后清空从指定数开始
    /// </summary>
    public sealed class SoftIncrementCount : IDisposable
    {
        #region Constructor

        /// <summary>
        /// 实例化一个自增信息的对象，包括最大值
        /// </summary>
        /// <param name="max">数据的最大值，必须指定</param>
        /// <param name="start">数据的起始值，默认为0</param>
        public SoftIncrementCount(long max, long start = 0)
        {
            this.start = start;
            this.max = max;
            current = start;
            hybirdLock = new SimpleHybirdLock();
        }

        #endregion

        #region Private Member

        private long start = 0;
        private long current = 0;
        private long max = long.MaxValue;
        private SimpleHybirdLock hybirdLock;

        #endregion

        #region Public Method

        /// <summary>
        /// 获取自增信息
        /// </summary>
        /// <returns>计数自增后的值</returns>
        public long GetCurrentValue()
        {
            long value = 0;
            hybirdLock.Enter();

            value = current;
            current++;
            if (current > max)
            {
                current = 0;
            }

            hybirdLock.Leave();
            return value;
        }


        #endregion

        #region IDisposable Support

        private bool disposedValue = false; // 要检测冗余调用

        void Dispose(bool disposing)
        {
            if (!disposedValue)
            {
                if (disposing)
                {
                    // TODO: 释放托管状态(托管对象)。

                    hybirdLock.Dispose();
                }

                // TODO: 释放未托管的资源(未托管的对象)并在以下内容中替代终结器。
                // TODO: 将大型字段设置为 null。


                disposedValue = true;
            }
        }

        // TODO: 仅当以上 Dispose(bool disposing) 拥有用于释放未托管资源的代码时才替代终结器。
        // ~SoftIncrementCount() {
        //   // 请勿更改此代码。将清理代码放入以上 Dispose(bool disposing) 中。
        //   Dispose(false);
        // }

        // 添加此代码以正确实现可处置模式。
        /// <summary>
        /// 释放当前对象所占用的资源
        /// </summary>
        public void Dispose()
        {
            // 请勿更改此代码。将清理代码放入以上 Dispose(bool disposing) 中。
            Dispose(true);
            // TODO: 如果在以上内容中替代了终结器，则取消注释以下行。
            // GC.SuppressFinalize(this);
        }

        #endregion
    }


}
